home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Workbench Add-On
/
Workbench Add-On - Volume 1.iso
/
BBS-Archive
/
Comm
/
AmiTCP30b2.lha
/
src
/
appl
/
napsaterm
/
tek4010.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-05-14
|
45KB
|
1,232 lines
/* Support for opening a tek4010 window from napsaterm on the Amiga. This
option is enabled if the symbol TEKTRONICS is defined at compile time. */
/* tek4010.c is by RKNOP, Robert Knop, rknop@mop.caltech.edu */
/* tek4010 version 1.4 beta */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "amiga.h"
#include "nifty.h"
#include "napsaprefs.h"
#include "wimp.h"
#include "nio.h"
#include "ascii_ctrl.h"
#include <graphics/displayinfo.h>
#include <graphics/gfxmacros.h>
#include <intuition/screens.h>
#include <libraries/asl.h>
#include <libraries/gadtools.h>
#include <proto/asl.h>
#include <proto/diskfont.h>
#include <proto/intuition.h>
#include <proto/gadtools.h>
#include <proto/graphics.h>
#include <proto/keymap.h>
#include <proto/console.h>
/*
#include <proto/exec.h>
*/
#ifdef TEKTRONICS
/*#echo "Compiling tek4010 unit"*/
/********** NOTE -- This is a hack I'm using to get bloody napsaterm to link
with the debugger! *************/
const UBYTE _DevName[]="Rob's Hack";
/**************** End of NOTE ***************************************************/
/* Local functions not needed by the outside */
int opentekwin(void);
void calctekwinsize(void);
void newtekfont(void);
int decode_integer(char);
void Safe_Move(struct RastPort *,WORD,WORD);
void Safe_Draw(struct RastPort *,WORD,WORD);
void Safe_Rect(struct RastPort *,WORD,WORD);
void scrtotek(void);
void graph_clear(void);
void setdrawmode(ULONG mode,WORD noerase);
void redrawtek(void);
void gin_mode_toggle(struct MenuItem *);
void ginmouse(struct IntuiMessage *msg);
void ginkeys(struct IntuiMessage *);
void sendreport(WORD,WORD,char);
void menu_close(void);
void tekmenu(struct IntuiMessage *);
void chk_active(struct MenuItem *);
void chk_front(struct MenuItem *);
#define FULLWIDTH 4096
#define FULLHEIGHT 3120
#define BUFFERSIZE 65536
int tekmode=0; /*Global variable, 1 if tek window is current window*/
int bypassmode=0;
static int fullcursor=0;
static char eolstring[]="\015\0\0"; /*End of report string <CR>*/
static mode=TEK_ALPHA;
static int buffermode=0;
#define DEF_ACTIVE CHECKED
#define DEF_FRONT CHECKED
static int activateonswitch=DEF_ACTIVE;
static int forwardonswitch=DEF_FRONT;
extern struct KeyMap *default_map; /* In keymap.c */
extern struct KeyMap *used_map; /* In keymap.c */
extern struct IOStdReq consolereq; /* In keymap.c */
#define ConsoleDevice (consolereq.io_Device)
extern struct Window *w; /*vt100 window in wimp.c*/
struct Window *tekwindow=NULL;
static WORD maxx,maxy,minx,miny;
long tekwinmask=0;
static int winw,winh;
static int tekwidth=FULLWIDTH,tekheight=FULLHEIGHT,tekleft=0,tekbot=0;
static Point Aspect;
static char *tekbuffer=NULL;
static char *startbuffer,*endbuffer;
#define ENDCHECK if (endbuffer<tekbuffer) endbuffer+=BUFFERSIZE;
static char tektitle[80];
/* Text/Font information */
static struct TextAttr deftekattr={"topaz.font",8,0x00,0x00};
static struct TextAttr tekattr;
static struct TextFont *tekfont;
/*Tektronics drawing variables*/
static int last_mode;
static int esc_mode=0;
static int first_vector=1,incr_pen_down=0;
static WORD increment=4; /*Move in incr mode*/
static WORD lastx,lasty; /*Previous position in screen coords*/
static WORD tekx,teky; /*Prev. pos. in tek coords*/
static UWORD lyok; /* Flag, is last y out of bounds*/
static char HiY,Extra,LoY,HiX,LoX; /*Tektronics position*/
static char LoYorExtra=0; /*temp storage for ambiguity*/
static char LastTag; /*Tag bits of last vector byte*/
/*********************************************************************************/
/* Open the tek4010 window on the napsaterm public screen */
/* By nature, it opens to the full size of the screen sans the title bar. */
/*********************************************************************************/
static struct NewMenu tekmenus[]=
{ {NM_TITLE, "TEK4010", 0, 0, 0, 0,},
{ NM_ITEM, "To VT102", "T", 0, 0, tek_vt100,},
{ NM_ITEM, "To Tek", "G", 0, 0, vt100_tek,},
{ NM_ITEM, "Graph Clear", "C", 0, 0, graph_clear,},
{ NM_ITEM, "Redraw", "R", 0, 0, redrawtek,},
{ NM_ITEM, "Set Font...", "F", 0, 0, newtekfont,},
{ NM_ITEM, NM_BARLABEL, 0, 0, 0, 0,},
{ NM_ITEM, "Close", "Q", 0, 0, menu_close,},
{NM_TITLE, "Config", 0, 0, 0, 0,},
{ NM_ITEM, "Activate Windows",0,MENUTOGGLE|CHECKIT|DEF_ACTIVE,0,chk_active,},
{ NM_ITEM, "Front Windows", 0,MENUTOGGLE|CHECKIT|DEF_FRONT,0,chk_front,},
{NM_TITLE, "GIN Cursor", 0, 0, 0, 0,},
{ NM_ITEM, "Cursor On", 0,MENUTOGGLE|CHECKIT,0,gin_mode_toggle,},
#define CURSOR_MENUNUM 2
{ NM_END, NULL, 0, 0, 0, 0,},
};
static APTR visinfo;
static struct Menu *menuStrip;
int opentekwin(void)
{ ULONG modeID;
struct DisplayInfo di;
struct Screen *s;
char *pubscname;
static int first=1; /*Flag, first call to opentekwin*/
if (!(tekbuffer=AllocMem(BUFFERSIZE,MEMF_PUBLIC))) return(0);
startbuffer=endbuffer=tekbuffer;
pubscname=np.pubscname;
s=LockPubScreen(pubscname); /*Try to lock the public screen*/
if (!s && pubscname) s=LockPubScreen(pubscname=NULL); /*Try def. pub scr*/
if (!s) /*Complete and utter failure*/
{ FreeMem(tekbuffer,65536);
return(0);
}
modeID=GetVPModeID(&s->ViewPort);
if (!GetDisplayInfoData(NULL,(UBYTE *)&di,sizeof(di),DTAG_DISP,modeID))
{ FreeMem(tekbuffer,65536);
UnlockPubScreen(NULL,s);
return(0);
}
Aspect.x=di.Resolution.x; Aspect.y=di.Resolution.y;
sprintf(tektitle,"%s (TEK-4010)",np.title ? np.title : ProgName);
tekwindow=
OpenWindowTags(NULL, WA_PubScreen,s , WA_Left,0 , WA_Top,s->BarHeight ,
WA_Width,s->Width , WA_Height,s->Height-s->BarHeight ,
WA_MinWidth,70 , WA_MinHeight, 30 ,
WA_MaxWidth,s->Width , WA_MaxHeight,s->Height ,
WA_ScreenTitle,ProgName , WA_Title,tektitle ,
WA_Flags,WFLG_SMART_REFRESH | WFLG_CLOSEGADGET |
WFLG_DEPTHGADGET | WFLG_DRAGBAR |
WFLG_NOCAREREFRESH | WFLG_ACTIVATE |
WFLG_SIZEGADGET ,
WA_IDCMP,IDCMP_CLOSEWINDOW | IDCMP_NEWSIZE |
IDCMP_MENUPICK | IDCMP_RAWKEY ,
TAG_DONE);
UnlockPubScreen(NULL,s);
if (!tekwindow) return(0);
visinfo=GetVisualInfo(s,TAG_END); /*Check ret val?*/
menuStrip=CreateMenus(tekmenus,TAG_END); /*Check return?*/
LayoutMenus(menuStrip,visinfo,TAG_END); /*Check return?*/
SetMenuStrip(tekwindow,menuStrip); /*Check return?*/
tekwinmask=1<<tekwindow->UserPort->mp_SigBit;
calctekwinsize();
setdrawmode(JAM1,1);
if (first)
{ tekattr=deftekattr; /*Set to default the first time only*/
first=0;
}
if (!(tekfont=OpenDiskFont(&tekattr)))
{ tekattr=deftekattr; /*Failed to open font, open topaz 8*/
tekfont=OpenDiskFont(&tekattr);
}
SetFont(tekwindow->RPort,tekfont); /*Set font for alpha mode*/
graph_clear(); /*Always start with cleared graphics screen*/
return(1);
}
/******************************************************************************/
/* closetekwin() -- close the tek window, quit tek terminal mode */
/******************************************************************************/
void closetekwin(void)
{ struct Message *msg;
if (!tekwindow) return;
tekmode=0;
tekwinmask=0;
while (msg=GetMsg(tekwindow->UserPort)) /*Clean messages out of user port*/
ReplyMsg(msg);
ClearMenuStrip(tekwindow); /*Get rid of those GadTools menus*/
FreeMenus(menuStrip);
FreeVisualInfo(visinfo);
CloseWindow(tekwindow);
tekwindow=NULL; /*Make sure we know there is no tekwindow*/
CloseFont(tekfont); /*Close the font, we no longer need it*/
FreeMem(tekbuffer,65536);
}
/******************************************************************************/
/* calctekwinsize() -- load winw and winh according to proper Tek screen size */
/******************************************************************************/
void calctekwinsize(void)
{ int w,h;
minx=tekwindow->BorderLeft;
maxx=tekwindow->Width-tekwindow->BorderRight-1;
w=maxx-minx;
miny=tekwindow->BorderTop;
maxy=tekwindow->Height-tekwindow->BorderBottom-1;
h=maxy-miny;
winh=h;
winw=(tekwidth*winh*Aspect.y) / (tekheight*Aspect.x);
if (winw>w)
{ winw=w;
winh=(tekheight*winw*Aspect.x) / (tekwidth*Aspect.y);
}
}
/*****************************************************************************/
/* Put up the ASL font requester to get a new font */
/*****************************************************************************/
void newtekfont(void)
{ struct FontRequester *req;
struct TextAttr oldattr;
if (!tekwindow) return;
if (!(req=(struct FontRequester *)AllocAslRequestTags(
ASL_FontRequest,ASL_FontName,(ULONG)tekattr.ta_Name,
ASL_FontHeight,(ULONG)tekattr.ta_YSize,
ASL_FuncFlags,FONF_FIXEDWIDTH,ASL_Window,tekwindow,TAG_END)))
return;
if (AslRequest(req,NULL))
{ oldattr=tekattr;
tekattr=req->fo_Attr;
CloseFont(tekfont); /*Close the old font*/
if (!(tekfont=OpenDiskFont(&tekattr))) /*Try to open new font*/
{ tekattr=oldattr;
if (!(tekfont=OpenDiskFont(&tekattr))) /*If fail, go back to old*/
{ tekattr=deftekattr;
tekfont=OpenDiskFont(&tekattr); /*If _that_ fails, go to topaz/8*/
}
}
SetFont(tekwindow->RPort,tekfont);
}
FreeAslRequest(req);
}
/*****************************************************************************/
/* Set tektronics mode */
/*****************************************************************************/
void set_tekmode(unsigned short newmode)
{ struct RastPort *rp;
WORD x,y;
rp=tekwindow->RPort;
if ((mode=newmode)==TEK_ALPHA) /*Do some bounds checking*/
{ if (!(rp->cp_x > (x=tekwindow->Width - tekwindow->BorderRight -
tekfont->tf_XSize)))
x=rp->cp_x;
if (!(rp->cp_y < (y=tekwindow->BorderTop + tekfont->tf_Baseline)))
y=rp->cp_y;
Move(rp,x,y); /*Now we know it is safe to render a letter*/
}
}
/****************************************************************************/
/* Switch from vt100 mode to tek mode without clearing the tek screen */
/****************************************************************************/
void vt100_tek(void)
{
if (!tekwindow)
{ if (!opentekwin()) return;
}
if (activateonswitch) ActivateWindow(tekwindow);
if (forwardonswitch) WindowToFront(tekwindow);
tekmode=1;
}
/*******************************************************************************/
/* Switch from tek mode to vt100 mode */
/*******************************************************************************/
void tek_vt100(void)
{
if (activateonswitch) ActivateWindow(w);
if (forwardonswitch) WindowToFront(w);
tekmode=0;
}
/******************************************************************************/
/* graph_clear() -- clear the graphics screen and the tek buffer */
/******************************************************************************/
void graph_clear(void)
{ WORD xscr,yscr;
startbuffer=endbuffer=tekbuffer;
SetAPen(tekwindow->RPort,0);
RectFill(tekwindow->RPort,tekwindow->BorderLeft,tekwindow->BorderTop,
tekwindow->Width-1-tekwindow->BorderRight,
tekwindow->Height-1-tekwindow->BorderBottom);
HiY=Extra=LoY=HiX=LoX=LoYorExtra=(char)0; /*Initialize tek position variables*/
first_vector=1; /*Always start out with first vector*/
esc_mode=0; /*Always clear escape mode*/
SetDrPt(tekwindow->RPort,0xffff); /*Start with solid draw pattern*/
setdrawmode(JAM1,1);
esc_mode=0; /*Start with esc_mode cleared*/
set_tekmode(TEK_ALPHA); /*Start in alpha mode -oo-*/
bypassmode=0; /*Start with bypass mode off*/
xscr=tekwindow->BorderLeft;
yscr=tekwindow->BorderTop+tekfont->tf_Baseline+1;
Safe_Move(tekwindow->RPort,xscr,yscr); /*Home*/
scrtotek();
}
/*****************************************************************************/
/* setdrawmode() -- changes drawing mode for screen */
/*****************************************************************************/
void setdrawmode(ULONG mode,WORD noerase)
{ struct DrawInfo *di;
if (di=GetScreenDrawInfo(tekwindow->WScreen))
{ if (noerase) SetAPen(tekwindow->RPort,di->dri_Pens[TEXTPEN]);
else SetAPen(tekwindow->RPort,di->dri_Pens[BACKGROUNDPEN]);
FreeScreenDrawInfo(tekwindow->WScreen,di);
}
else
{ if (noerase) SetAPen(tekwindow->RPort,1);
else SetAPen(tekwindow->RPort,0);
}
SetDrMd(tekwindow->RPort,mode);
}
/*****************************************************************************/
/* gin_mode_toggle() -- turn on/off GIN cursor */
/*****************************************************************************/
/**** NOTE : deal with setting the checkmark in the menu!!!! *****/
/**** Also deal with setting the pointer to crosshairs ****/
UWORD __chip Crosshairs[] = /*Done by hand*/
{ 0x0000,0x0000, /* Two system reserved words */
0x0000,0x0000,
0x0000,0x0100,
0x7efc,0x0100,
0x4004,0x0100,
0x4004,0x0100,
0x4004,0x0100,
0x4004,0x0100,
0x4004,0x0100,
0x0100,0xfffe,
0x4004,0x0100,
0x4004,0x0100,
0x4004,0x0100,
0x4004,0x0100,
0x4004,0x0100,
0x7efc,0x0100,
0x0000,0x0100,
0x0000,0x0000 /* Two more system reserved words */
};
void gin_mode_toggle(struct MenuItem *menu)
{ static int lasttekmode=TEK_ALPHA,lastbuffermode;
struct MenuItem *item;
if (menu) item=menu;
else item=ItemAddress(menuStrip,CURSOR_MENUNUM);
if ( (menu && (item->Flags&CHECKED)) || ((!menu) && (mode!=TEK_GIN)) )
{ lasttekmode=mode;
lastbuffermode=buffermode;
buffermode=0;
set_tekmode(TEK_GIN);
bypassmode=1;
if (fullcursor)
ModifyIDCMP(tekwindow,tekwindow->IDCMPFlags |
IDCMP_MOUSEMOVE|IDCMP_MOUSEBUTTONS);
else ModifyIDCMP(tekwindow,tekwindow->IDCMPFlags|IDCMP_MOUSEBUTTONS);
SetPointer(tekwindow,Crosshairs,16,16,-8,-8);
item->Flags|=CHECKED;
ResetMenuStrip(tekwindow,menuStrip);
}
else
{ set_tekmode(lasttekmode);
/*set_tekmode(TEK_ALPHA);*/
lasttekmode=TEK_ALPHA;
buffermode=lastbuffermode;
bypassmode=0;
ModifyIDCMP(tekwindow,tekwindow->IDCMPFlags &
~(IDCMP_MOUSEMOVE|IDCMP_MOUSEBUTTONS));
ClearPointer(tekwindow);
item->Flags &= ~CHECKED;
ResetMenuStrip(tekwindow,menuStrip);
}
}
/*****************************************************************************/
/* ginmouse() -- deal with GIN mouse events */
/*****************************************************************************/
void ginmouse(struct IntuiMessage *msg)
{ WORD xscr,yscr,xgin,ygin;
if (msg->Class==MOUSEMOVE)
{ /* Deal with moving big crosshairs if necessary */
}
else if (msg->Class==MOUSEBUTTONS)
{ if (msg->Code==SELECTDOWN)
{ Forbid();
xscr=tekwindow->MouseX;
yscr=tekwindow->MouseY;
Permit();
xgin=((xscr-tekwindow->BorderLeft)*tekwidth)/winw;
ygin=(-(yscr-tekwindow->BorderTop-winh)*tekheight)/winh;
sendreport(xgin,ygin,' ');
gin_mode_toggle(NULL); /*quit GIN mode*/
}
}
ReplyMsg((struct Message *)msg);
}
/*****************************************************************************/
/* ginkeys() -- deal with GIN RAWKEY events */
/*****************************************************************************/
void ginkeys(struct IntuiMessage *msg)
{ struct InputEvent ie;
char buf[4];
WORD xscr,yscr,xgin,ygin;
if (msg->Code & IECODE_UP_PREFIX) return;
ie.ie_Code=msg->Code;
ie.ie_NextEvent=NULL;
ie.ie_SubClass=0;
ie.ie_Class=IECLASS_RAWKEY;
ie.ie_Qualifier=msg->Qualifier;
ie.ie_position.ie_addr=*((APTR *)msg->IAddress);
RawKeyConvert(&ie,buf,4,np.national ? used_map : default_map);
/*** Send report with mouse x,y tek position */
Forbid();
xscr=tekwindow->MouseX;
yscr=tekwindow->MouseY;
Permit();
xgin=((xscr-tekwindow->BorderLeft)*tekwidth)/winw;
ygin=(-(yscr-tekwindow->BorderTop-winh)*tekheight)/winh;
sendreport(xgin,ygin,buf[0]);
ReplyMsg((struct Message *)msg);
gin_mode_toggle(NULL);
}
/*****************************************************************************/
/* sendreport() -- Send 4010 style report to host */
/* Pass x,y in 4014 4096-pixel coordinate system. */
/* This routine converts it to 1024 before sending the report */
/*****************************************************************************/
void sendreport(WORD x,WORD y,char c)
{ char report[10];
int i=-1,j;
if (c) report[++i]=c;
switch (mode) /* Set bits 2-3 of status based on mode*/
{ case TEK_POINT : report[++i]=0x01; break; /* Bit 0 always set */
case TEK_ALPHA : report[++i]=0x05; break;
case TEK_VECTOR : report[++i]=0x09; break;
case TEK_GIN : break;
default : report[++i]=0x0d; break;
}
report[++i]=0x20 | ( (x & 0x0f80)>>7 ); /*HiX*/
report[++i]=0x20 | ( (x & 0x007c)>>2 ); /*LoX*/
report[++i]=0x20 | ( (y & 0x0f80)>>7 ); /*HiY*/
report[++i]=0x20 | ( (y & 0x007c)>>2 ); /*LoY*/
for (j=0;j<strlen(eolstring);j++)
report[++i]=eolstring[j];
report[++i]='\0';
nwrite(report,i);
}
/*****************************************************************************/
/* redrawtek() -- redraw tek window from buffer */
/*****************************************************************************/
void redrawtek(void)
{ char *c;
/* Start with a simulation of graph_clear, all but the buffer clearing*/
SetAPen(tekwindow->RPort,0);
RectFill(tekwindow->RPort,tekwindow->BorderLeft,tekwindow->BorderTop,
tekwindow->Width-1-tekwindow->BorderRight,
tekwindow->Height-1-tekwindow->BorderBottom);
HiY=Extra=LoY=HiX=LoX=LoYorExtra=(char)0; /*Initialize tek position variables*/
first_vector=1; /*Always start out with first vector*/
esc_mode=0; /*Always clear escape mode*/
SetDrPt(tekwindow->RPort,0xffff); /*Start with solid draw pattern*/
setdrawmode(JAM1,1);
buffermode=1;
if (startbuffer>endbuffer)
{ c=tekout(startbuffer,tekbuffer+BUFFERSIZE);
c=tekout(tekbuffer,endbuffer);
}
else c=tekout(startbuffer,endbuffer);
buffermode=0;
/* Deal with c not being equal to text+count*/
}
/********************************************************************************/
/* tekout() -- handle characters incoming into the Tek screen */
/* Generally, this will be called from termout (see emulate.c). It returns */
/* a pointer to the first charcter after a return to VT100 mode, or to */
/* endtext. This way, termout can call tekout and use it's return value for */
/* updating its pointer into the string of characters which have been handled*/
/********************************************************************************/
/***** Meanings of esc modes:
0 no escape
1 ESC
2 ESC [ or CSI
3 ESC "
4 ESC [ ?
6 ESC %
7 ESC % !
****/
char *tekout(char *text,char *endtext)
{ char *c;
WORD xscr,yscr,xgin,ygin;
static int esc_number=0,seq_length=0;
for (c=text;c<endtext;c++)
{ if (!buffermode)
{ *endbuffer=*c;
if (endbuffer-tekbuffer==BUFFERSIZE-1) endbuffer=tekbuffer;
else endbuffer++;
if (startbuffer>=endbuffer)
{ startbuffer++;
if (startbuffer-tekbuffer==BUFFERSIZE-1) startbuffer=tekbuffer;
}
}
if (mode==TEK_GIN) /* GIN (bypass) mode sequences */
{ switch(*c)
{ case ESC : if (esc_mode) {}
else
{ esc_mode=1;
esc_number=0;
}
break;
case ENQ : if (esc_mode==1)
{ Forbid();
xscr=tekwindow->MouseX;
yscr=tekwindow->MouseY;
Permit();
xgin=((xscr-tekwindow->BorderLeft)*tekwidth)/winw;
ygin=(-(yscr-tekwindow->BorderTop-winh)*tekheight)/winh;
sendreport(xgin,ygin,'\0');
gin_mode_toggle(NULL); /*quit GIN mode*/
}
break;
case LF :
case CR : gin_mode_toggle(NULL); /*quit GIN mode, don't*/
break; /* change esc_mode */
case BS :
case VT :
case HT : if (esc_mode==0) gin_mode_toggle(NULL);
else esc_mode=0;
break;
case BEL : DisplayBeep(tekwindow->WScreen);
esc_mode=0;
gin_mode_toggle(NULL);
break;
case CAN :
case SUB : esc_mode=0; /* -oo- These just set bypass or GIN */
break;
case US : esc_mode=0;
gin_mode_toggle(NULL);
set_tekmode(TEK_ALPHA);
break;
case FF : if (esc_mode==1)
{ gin_mode_toggle(NULL);
graph_clear();
}
break;
}
} /*End of GIN mode handling */
else if (!esc_mode && (*c>=0x20)) /*If not a CTRL char or ESC sequence...*/
{ if ((mode==TEK_VECTOR)||(mode==TEK_POINT)||(mode==TEK_BLOCK))
{ if (decode_integer(*c)) /*Non-zero result indicates LoX rec.*/
{ tekx=((short)(HiX & 0x1f)<<7) | /*Build new X tek position*/
((short)(LoX & 0x1f)<<2) |
((short)(Extra & 0x03));
teky=((short)(HiY & 0x1f)<<7) | /*Build new Y tek position*/
((short)(LoY & 0x1f)<<2) |
((short)(Extra & 0x0c)>>2);
xscr=tekwindow->BorderLeft+(tekx*winw)/tekwidth; /*Screen position*/
yscr=tekwindow->BorderTop+winh-(teky*winh)/tekheight;
if (mode==TEK_POINT)
{ WritePixel(tekwindow->RPort,xscr,yscr); /*Does check bounds*/
Safe_Move(tekwindow->RPort,xscr,yscr);
}
else
{ if (first_vector)
{ Safe_Move(tekwindow->RPort,xscr,yscr);
first_vector=0;
}
else
{ if (mode==TEK_VECTOR)
Safe_Draw(tekwindow->RPort,xscr,yscr);
else
Safe_Rect(tekwindow->RPort,xscr,yscr);
}
}
}
} /*End of TEK_VECTOR and TEK_POINT handling*/
else if (mode==TEK_ALPHA)
{ if (tekwindow->RPort->cp_x >
tekwindow->Width-tekwindow->BorderRight-tekfont->tf_XSize)
{ xscr=tekwindow->BorderLeft;
yscr=tekwindow->RPort->cp_y+tekfont->tf_YSize+1;
if ( (yscr+tekfont->tf_YSize-tekfont->tf_Baseline) >
tekwindow->Height-tekwindow->BorderBottom )
yscr=tekwindow->BorderTop+tekfont->tf_Baseline+1;
Safe_Move(tekwindow->RPort,xscr,yscr);
}
Text(tekwindow->RPort,c,1); /*Write the character*/
} /*End of TEK_ALPHA handling*/
else if (mode==TEK_INCR)
{ if (*c==' ') incr_pen_down=0;
else if (*c=='P') incr_pen_down=1;
else
{ switch(*c)
{ case 'D' : teky+=1; break;
case 'E' : teky+=1; tekx+=1; break;
case 'A' : tekx+=1; break;
case 'I' : teky-=1; tekx+=1; break;
case 'H' : teky-=1;
case 'J' : teky-=1; tekx-=1; break;
case 'B' : tekx-=1;
case 'F' : tekx-=1; teky+=1; break;
}
xscr=tekwindow->BorderLeft+(tekx*winw)/tekwidth; /*Screen position*/
yscr=tekwindow->BorderTop+winh-(teky*winh)/tekheight;
Safe_Draw(tekwindow->RPort,xscr,yscr);
}
}
}
/* NOTE -- ESC sequences will be interpreted in all modes, even if they
aren't supposed to be. Fix this later?*/
/* GIN mode is a special case, above */
else /*Handling of ESC sequences and CTRL codes*/
{ ++seq_length;
if ((esc_mode==3 || esc_mode==4) && *c>='0' && *c<='9')
esc_number=10*esc_number+ *c-'0';
else switch(*c) /* *c is a control character of some sort*/
{ /* Vector & Point mode sequences */
case ESC : if (esc_mode) {} /* ESC ESC == ESC */
else
{ esc_mode=seq_length=1;
esc_number=0;
}
break;
case STX : if (esc_mode==1 && mode==TEK_VECTOR)
{ set_tekmode(TEK_BLOCK);
first_vector=1;
}
esc_mode=0;
break;
case ETX : if (esc_mode==1 && mode==TEK_BLOCK)
{ set_tekmode(TEK_VECTOR);
first_vector=1;
}
esc_mode=0;
break;
case SOH : if (esc_mode==1) setdrawmode(JAM1,1);
esc_mode=0; /*Writing mode = draw*/
break;
case DLE : if (esc_mode==1) setdrawmode(JAM1,0);
esc_mode=0; /*Writing mode = erase*/
break;
case NAK : if (esc_mode==1) setdrawmode(INVERSVID,1);
esc_mode=0; /*Writing mode=invert*/
break;
case EM : if (esc_mode==1) setdrawmode(JAM2,1);
esc_mode=0; /*Writing mode=replace*/
break;
case BEL : DisplayBeep(tekwindow->WScreen);
esc_mode=0;
break;
case CR : if (mode!=TEK_ALPHA) mode=TEK_ALPHA;
else
{ Safe_Move(tekwindow->RPort,tekwindow->BorderLeft,
tekwindow->RPort->cp_y);
scrtotek();
}
break;
case FF : if (esc_mode==1)
{ graph_clear(); /*More??*/
if (mode==TEK_INCR) set_tekmode(TEK_ALPHA);
}
esc_mode=0;
break;
case CAN : if (esc_mode==0)
{ tek_vt100(); /*Switch back to vt100 mode*/
if (!buffermode)
{ endbuffer--; /*Kill vt100 esc seq from buffer*/
ENDCHECK;
}
return(++c); /*Return position to keep going*/
}
else if (esc_mode==1)
{ /*set bypass condition -oo- !!!!!!!!!*/
esc_mode=0;
if (mode==TEK_ALPHA) graph_clear();
}
else esc_mode=0;
break;
case SUB : if (esc_mode==1)
{ gin_mode_toggle(NULL);
if (!buffermode)
{ endbuffer-=seq_length; /*No buffering GIN mode*/
ENDCHECK;
}
esc_mode=esc_number=0;
}
else esc_mode=0;
break;
case FS : set_tekmode(TEK_POINT);
esc_mode=0;
break;
case GS : set_tekmode(TEK_VECTOR);
esc_mode=0;
first_vector=1;
break;
case RS : set_tekmode(TEK_INCR);
esc_mode=0;
break;
case US : set_tekmode(TEK_ALPHA);
esc_mode=0;
break;
case '`' : if (esc_mode==1)
{ SetDrPt(tekwindow->RPort,0xffff);
SetAPen(tekwindow->RPort,1);
esc_mode=0;
}
break;
case 'a' : if (esc_mode==1)
{ SetDrPt(tekwindow->RPort,0xaaaa);
SetAPen(tekwindow->RPort,1);
}
esc_mode=0;
break;
case 'b' : if (esc_mode==1)
{ SetDrPt(tekwindow->RPort,0xfafa);
SetAPen(tekwindow->RPort,1);
}
esc_mode=0;
break;
case 'c' : if (esc_mode==1)
{ SetDrPt(tekwindow->RPort,0xeeee);
SetAPen(tekwindow->RPort,1);
}
esc_mode=0;
break;
case 'd' : if (esc_mode==1)
{ SetDrPt(tekwindow->RPort,0xfcfc);
SetAPen(tekwindow->RPort,1);
}
esc_mode=0;
break;
case 'e' : if (esc_mode==1)
{ SetDrPt(tekwindow->RPort,0xff55);
SetAPen(tekwindow->RPort,1);
}
esc_mode=0;
break;
case 'f' : if (esc_mode==1)
{ SetDrPt(tekwindow->RPort,0xff6c);
SetAPen(tekwindow->RPort,1);
}
esc_mode=0;
break;
case 'g' : if (esc_mode==1)
{ SetDrPt(tekwindow->RPort,0xf0f0);
SetAPen(tekwindow->RPort,1);
}
else if (esc_mode==3) /*From SuperMode*/
{ tek_vt100();
if (!buffermode)
{ endbuffer-=seq_length; /*Remove to vt100 seq from buf*/
ENDCHECK;
}
esc_mode=0;
return(++c);
}
/* Note -- I ought to check to make sure there was a 0*/
esc_mode=0;
break;
case 'h' : if (esc_mode==1)
{ SetDrPt(tekwindow->RPort,0xffff);
SetAPen(tekwindow->RPort,2);
}
else if (esc_mode==4) /*ESC [ ? <number> h*/
{ if (esc_number==38) {} /*Switch to tek-- do nil*/
}
esc_mode=0;
break;
case 'i' : if (esc_mode==1)
{ SetDrPt(tekwindow->RPort,0xaaaa);
SetAPen(tekwindow->RPort,2);
}
esc_mode=0;
break;
case 'j' : if (esc_mode==1)
{ SetDrPt(tekwindow->RPort,0xfafa);
SetAPen(tekwindow->RPort,2);
}
esc_mode=0;
break;
case 'k' : if (esc_mode==1)
{ SetDrPt(tekwindow->RPort,0xeeee);
SetAPen(tekwindow->RPort,2);
}
esc_mode=0;
break;
case 'l' : if (esc_mode==1)
{ SetDrPt(tekwindow->RPort,0xfcfc);
SetAPen(tekwindow->RPort,2);
}
else if (esc_mode==4) /*ESC [ ? <number> l*/
{ if (esc_number==38) /*Switch to vt100*/
{ esc_mode=0;
tek_vt100();
if (!buffermode)
{ endbuffer-=seq_length; /*Remove esc seq from buffer*/
ENDCHECK;
}
return(++c);
}
}
esc_mode=0;
break;
case 'm' : if (esc_mode==1)
{ SetDrPt(tekwindow->RPort,0xff55);
SetAPen(tekwindow->RPort,2);
}
esc_mode=0;
break;
case 'n' : if (esc_mode==1)
{ SetDrPt(tekwindow->RPort,0xff6c);
SetAPen(tekwindow->RPort,2);
}
esc_mode=0;
break;
case 'o' : if (esc_mode==1)
{ SetDrPt(tekwindow->RPort,0xf0f0);
SetAPen(tekwindow->RPort,2);
}
esc_mode=0;
break;
case '?' : if (esc_mode==1)
{ LoY=0x7f; /*DEL character replacement*/
esc_mode=0;
}
else if (esc_mode==2) /*<CSI>*/
esc_mode=4;
else esc_mode=0;
break;
/* End of Vector Mode sequences*/
/* Alpha mode sequences */
/* See Vector mode for ESC,BEL,ESC/FF,ESC/SUB,FS,GS,RS,CR*/
case ENQ : /* -oo- report terminal status */
if (esc_mode) esc_mode=0;
break;
case DEL: if (esc_mode) break;
/* Otherwise same as BS */
case BS : /* Move one space left */
if (esc_mode) esc_mode=0;
if (mode==TEK_ALPHA)
{ if (tekwindow->RPort->cp_x < tekfont->tf_XSize)
xscr=tekwindow->BorderLeft;
else xscr=tekwindow->RPort->cp_x-tekfont->tf_XSize;
Safe_Move(tekwindow->RPort,xscr,tekwindow->RPort->cp_y);
scrtotek();
}
break;
case HT : /*Horiz tab*/
if (esc_mode) esc_mode=0;
break;
case LF : /*CRLF*/
if ( esc_mode==0 && mode==TEK_ALPHA )
{ xscr=tekwindow->BorderLeft;
yscr=tekwindow->RPort->cp_y+tekfont->tf_YSize+1;
if ( (yscr+tekfont->tf_YSize-tekfont->tf_Baseline) >
tekwindow->Height-tekwindow->BorderBottom )
yscr=tekwindow->BorderTop+tekfont->tf_Baseline+1;
Safe_Move(tekwindow->RPort,xscr,yscr);
scrtotek();
}
/* esc_mode=0; */ /* ESC LF == ESC */
break;
case VT : /*Move one line up*/
if (esc_mode) esc_mode=0;
break;
/* End of Alpha mode sequences*/
/* Incremental Plot Mode sequences*/
/* End of Incremental Plot Mode sequences*/
/* SuperMode sequences -- this needs some work!*/
case '"' : if (esc_mode==1) esc_mode=3;
else esc_mode=0;
break;
case '[' : if (esc_mode==1) esc_mode=2; /*<CSI>*/
else esc_mode=0;
break;
case '%' : if (esc_mode==1) esc_mode=6;
else esc_mode=0;
break;
case '!' : if (esc_mode==6) esc_mode=7;
else esc_mode=0;
break;
case '0' : if (esc_mode==7) vt100_tek();
esc_mode=0;
break;
case '1' : if (esc_mode==7)
{ tek_vt100();
if (!buffermode)
{ endbuffer-=seq_length; /*Remove esc seq from buffer*/
ENDCHECK;
}
}
esc_mode=0;
break;
case '2' : if (esc_mode==1)
{ tek_vt100();
if (!buffermode)
{ endbuffer-=seq_length;
ENDCHECK;
}
}
esc_mode=0;
break;
/* case g h l ? handled above */
/* End of SuperMode sequences */
default : if (esc_mode) esc_mode=0;
break;
} /*End of switch over escaped characters*/
}
} /*End of the massive for loop over input characters*/
return(c); /*Should be text+count*/
}
/**********************************************************************/
/* decode_integer() Works on decoding a Tek integer */
/* Returns 1 if LoX was received, and terminal should act on the */
/* integer that has just been built. */
/**********************************************************************/
int decode_integer(char c)
{ char tagbits;
int rv;
rv=0;
tagbits=c & 0x60;
if (tagbits==0x20) /*HiY or HiX*/
{ if (LastTag==0x60) /*Last was LoY, this is HiX*/
{ HiX=c;
if (LoYorExtra)
{ LoY=LoYorExtra;
LoYorExtra=0;
}
}
else HiY=c;
}
else if (tagbits==0x60) /*LoY or Extra*/
{ if (LastTag==0x60) /*Last was Extra, this is LoY*/
{ Extra=LoYorExtra;
LoYorExtra=0;
LoY=c;
}
else /*Unknown if LoY or Extra*/
LoYorExtra=c;
}
else if (tagbits==0x40) /*LoX, draw the vector whatever*/
{ if (LastTag==0x60 && LoYorExtra) /* last was LoY */
LoY=LoYorExtra;
LoX=c;
rv=1;
}
LastTag=tagbits;
return(rv);
}
/********************************************************************************/
/* Draw to tekwindow, first checking to make sure we don't go outside boudries */
/* Note: because coordinates are represented with 12-bit unsigned integers, */
/* it is impossible for x to be out of bounds, and y can only be too large */
/* (assuming a y resolution of 3025 rather than 4096) */
/********************************************************************************/
void Safe_Move(struct RastPort *rp,WORD x,WORD y)
{
lastx=x; lasty=y;
if (!(lyok=(y<=maxy))) y=maxy;
Move(rp,x,y);
}
void Safe_Draw(struct RastPort *rp,WORD x,WORD y)
{ WORD x0;
if (y<=maxy)
{ if (lyok) Draw(rp,x,y); /*All clear*/
else
{ x0=x + (maxy-y) * (lastx-x) / (lasty-y);
Move(rp,x0,maxy);
Draw(rp,x,y);
}
}
else
{ if (!lyok) Safe_Move(rp,x,y); /*Won't draw anyway*/
else
{ x0=lastx + (maxy-lasty) * (x-lastx) / (y-lasty);
Draw(rp,x0,maxy);
}
}
lastx=x; lyok=((lasty=y)<=maxy);
}
void Safe_Rect(struct RastPort *rp,WORD x,WORD y)
{ WORD xmin,xmax,ymin,ymax;
if (y<=maxy) ymax=y; else ymax=maxy;
if (lyok) ymin=lasty; else ymin=maxy;
if (ymin>ymax) { xmin=ymin; ymin=ymax; ymax=xmin; }
if (lastx>x) { xmax=lastx; xmin=x; }
else { xmin=lastx; xmax=x; }
RectFill(rp,xmin,ymin,xmax,ymax);
lastx=x; lyok=((lasty=y)<=maxy);
}
/*****************************************************************************/
/* Convert screen coords in lastx,lasty to tek coords in tekx,teky */
/*****************************************************************************/
void scrtotek()
{
tekx=((lastx-tekwindow->BorderLeft)*tekwidth) / winw;
teky=((tekwindow->BorderTop+winh-lasty)*tekheight) / winh;
}
/********************************************************************************/
/* Accept IDCMP events from tek window */
/********************************************************************************/
void tekpoll(void)
{
struct IntuiMessage *msg;
while (tekwindow && (msg=(struct IntuiMessage *)GetMsg(tekwindow->UserPort)))
{ switch(msg->Class)
{ case RAWKEY : if (bypassmode) ginkeys(msg);
else dokeys(msg); /* Send to vt100 key handler */
break;
case CLOSEWINDOW : ReplyMsg((struct Message *)msg);
closetekwin();
tekmode=0;
break;
case NEWSIZE : calctekwinsize();
ReplyMsg((struct Message *)msg);
/* graph_clear();*/
redrawtek();
break;
case MENUPICK : tekmenu(msg);
break;
case MOUSEMOVE:
case MOUSEBUTTONS: if (mode==TEK_GIN) ginmouse(msg);
else ReplyMsg((struct Message *)msg);
break;
default: ReplyMsg((struct Message *)msg);
}
}
}
/*****************************************************************************/
/* Deal with menu events */
/*****************************************************************************/
static int close_it=0;
void menu_close(void)
{ close_it=1;
}
void tekmenu(struct IntuiMessage *msg)
{ UWORD Code; /*,menuNum,itemNum,subNum;*/
struct MenuItem *item;
void (*func)(struct MenuItem *);
close_it=0;
Code=msg->Code;
while ((Code!=MENUNULL) && (!close_it))
{ item=ItemAddress(menuStrip,Code);
/***
menuNum=MENUNUM(Code);
itemNum=ITEMNUM(Code);
subNum=SUBNUM(Code);
***/
func=(void(*)())GTMENUITEM_USERDATA(item);
(*func)(item);
Code=item->NextSelect;
}
ReplyMsg((struct Message *)msg);
if (close_it)
{ closetekwin();
tekmode=0;
}
}
/*****************************************************************************/
/* Check state of activatewindow and frontwindow menuitems */
/*****************************************************************************/
void chk_active(struct MenuItem *item)
{
activateonswitch = item->Flags & CHECKED;
}
void chk_front(struct MenuItem *item)
{
forwardonswitch = item->Flags & CHECKED;
}
#endif /*end of ifdef TEKTRONICS*/